<template>
  <div key="konva-map" class="konva-map relative-position col overflow-hidden">
    <template v-if="canEdit">
      <TopTools></TopTools>
      <ContextMenus :openedMap="openedMap"></ContextMenus>
    </template>
    <div class="fit map-canvas" @contextmenu="boxContext" @mousemove="boxMousemove"></div>
    <ZoomTool>
      <template v-if="$slots['map-tools']" v-slot:map-tools>
        <slot name="map-tools"></slot>
      </template>
      <div class="text-right relative-position text-caption text-grey-7">
        {{ `${XYCoor.x}, ${XYCoor.y}` }}
      </div>
    </ZoomTool>
    <div class="map-tips absolute text-caption">
      <span class="q-mr-md">{{ modeTips }}</span>
      <span>{{ $t('MapCore.GroundCodeType') }}: {{ openedMap?.mapGroundCode }}</span>
    </div>
    <RightBar :openedMap="openedMap"></RightBar>
    <div v-show="showPointerTips" :style="{ left: `${tipPosition.x}px`, top: `${tipPosition.y + 3}px` }"
      class="absolute">
      <q-tooltip v-model="showPointerTips" :offset="[0, 0]" anchor="bottom left"
        class="pointer-tips text-body2 bg-grey-7 q-pa-sm rounded-borders text-white" self="top left">
        <div class="text-no-wrap">
          {{ `${$t('MapCore.Coord')}：${tipsPointer.x ?? 0}, ${tipsPointer.y ?? 0}` }}
        </div>
        <div class="text-no-wrap q-pt-xs">{{ `${$t('MapCore.StationCode')}：${formatPointName(tipsPointer)}` }}</div>
        <div class="text-no-wrap q-pt-xs">
          {{ `${$t('MapCore.StationType')}：${formatPointType(tipsPointer.pointType)}` }}
        </div>
      </q-tooltip>
    </div>
    <q-resize-observer @resize="resizeCanvas"></q-resize-observer>
  </div>
  <AttrsDrawer :openedMap="openedMap"></AttrsDrawer>
  <CreateAreaText :openedMap="openedMap"></CreateAreaText>
</template>

<script setup>
import { i18n } from 'boot/i18n'
import { createWarnTips, formatNumber } from 'src/utils/utils'
import {
  clearSelected, destroyCanvas, exportAttrs, initCanvas, loadMap, offOperEvent, onInitEvent, onOperEvent,
  setAttrsModal, setCanUndoRedo, setCurrentAction, showPointerTips, tipPosition, tipsPointer, updateCanvas
} from 'src/views/MapCore/MapGlobal/utils/KonvaEvent'
import { packagePoints } from 'src/views/MapCore/MapGlobal/utils/PackagePoints'
import {
  batchUpdateLineAttrs, batchUpdatePointAttrs, updateAreaAttrs, updateLineAttrs, updatePointAttrs, updateTextAttrs
} from 'src/views/MapCore/MapGlobal/utils/utils'
import TopTools from 'src/views/MapCore/MapMaking/TopTools.vue'
import ZoomTool from 'src/views/MapCore/MapGlobal/Tools/ZoomTool.vue'
import RightBar from 'src/views/MapCore/MapGlobal/Tools/RightBar.vue'
import AttrsDrawer from 'src/views/MapCore/MapGlobal/AttrTools/AttrsDrawer.vue'
import CreateAreaText from 'src/views/MapCore/MapGlobal/AttrTools/CreateAreaText.vue'
import ContextMenus from './Contextmenus.vue'
import { computed, onBeforeUnmount, onMounted, provide, ref, watch } from 'vue'
import {
  calculateCoord, initGroupToolsBar, initZoomCanvas, moveLinesPointsBySelectedPoints
} from 'src/views/MapCore/MapGlobal/utils/MouseEvent'

const props = defineProps({
  mapMode: String, loading: Boolean, openedMap: Object, mapJSON: String,
  refreshMap: Boolean
})
const emits = defineEmits(['update:loading', 'update:refreshMap'])

let CANVAS = null
const screenSize = ref({}), XYCoor = ref({ x: 0, y: 0 })

const canEdit = computed(() => props.mapMode === 'edit')
const modeTips = computed(() => {
  const { mapMode } = props
  if (mapMode === 'demo') return i18n.t('MapCore.DemoMode')
  if (mapMode === 'edit') return i18n.t('MapCore.EditMode')
  if (mapMode === 'preview') return i18n.t('MapCore.PreviewMode')
  if (mapMode === 'monitor') return i18n.t('MapCore.MonitorMode')
  return ''
})

watch(() => props.mapMode, mapMode => {
  if (mapMode === 'edit') onOperEvent()
  else offOperEvent(void 0)
  console.log(mapMode, '----')
  setCurrentAction('move')
  setCanUndoRedo([], '', true)
})
watch(() => props.refreshMap, val => {
  if (!val) return
  const { mapJSON = '' } = props || {}, { mapGroundCode } = props.openedMap || {}
  console.log(val, '++++')
  loadMap(JSON.parse(mapJSON) || {}, () => {
    CANVAS && CANVAS.name(mapGroundCode)
    emits('update:loading', true)
  }, () => {
    emits('update:loading', false)
    emits('update:refreshMap', false)
  })

  initGroupToolsBar()
})
onMounted(() => {
  CANVAS = initCanvas('map-canvas', (canvas) => {
    if (!canvas) return
    if (screenSize.value.width) canvas.size(screenSize.value)
    initZoomCanvas(canvas)
    onInitEvent()
  })
})
const resizeCanvas = size => {
  screenSize.value = size
  if (!CANVAS) return
  const { width, height } = CANVAS.size()
  if (width !== size.width || height !== size.height) CANVAS && CANVAS.size(size)
}

const boxContext = e => e.preventDefault()
const boxMousemove = e => {
  e.preventDefault()
  XYCoor.value = calculateCoord(CANVAS)
}

const formatPointName = point => {
  if (!point) return ''
  const x = formatNumber((point.x || 0) * 1000) + '', y = formatNumber((point.y || 0) * 1000) + ''
  return `${x.padStart(6, '0')}${props.openedMap?.mapGroundCode || ''}${y.padStart(6, '0')}`
}
const formatPointType = code => (packagePoints.value.find(p => p.positionPackageCode === code) ||
  {}).positionPackageName || ''
const updateShapeCoord = form => {
  const { operShape } = exportAttrs(), { action } = form
  if (!operShape) return
  const { areaGroup, pointGroup, textGroup } = updateCanvas(void 0)
  if (action === 'area') return updateAreaAttrs(areaGroup, textGroup, operShape, form, true)
  if (action === 'text') return updateTextAttrs(textGroup, operShape, form, true)
  if (action === 'point') {
    const { x = 0, y = 0 } = operShape.getAttrs()
    if (form.x !== x || form.y !== y) {
      const findPoint = pointGroup.findOne(el => el.x() === form.x && el.y() === form.y)
      if (findPoint) return createWarnTips({ title: i18n.t('MapCore.OperationTip1') })
      const moveInfo = { type: 'assignXY', x: form.x, y: form.y }
      moveLinesPointsBySelectedPoints(CANVAS, [operShape], moveInfo)
    }
  }
}
const updateShapeAttrs = async (form, done) => {
  const { operShape, batchSelected = [] } = exportAttrs(), { action } = form
  if (action === 'line') updateLineAttrs(operShape, form)
  else if (action === 'point') updatePointAttrs(operShape, batchSelected, form).then()
  else if (action === 'area') {
    const { areaGroup, textGroup } = updateCanvas(void 0)
    updateAreaAttrs(areaGroup, textGroup, operShape, form)
  } else if (action === 'text') {
    updateTextAttrs(CANVAS.findOne('.texts'), operShape, form)
  }
  if (done) done()
}
const batchUpdateShapeAttrs = async (form, done, mDone) => {
  const { batchSelected = [] } = exportAttrs(), { action } = form
  if (action === 'line') {
    batchUpdateLineAttrs(CANVAS.findOne('.lines'), batchSelected, form)
  } else if (action === 'point') {
    batchUpdatePointAttrs(CANVAS, batchSelected, form)
    setAttrsModal(false)
  }
  clearSelected()
  if (done) done()
  if (mDone) mDone()
}
provide('updateShapeAttrs', updateShapeAttrs)
provide('updateShapeCoord', updateShapeCoord)
provide('batchUpdateShapeAttrs', batchUpdateShapeAttrs)

onBeforeUnmount(() => {
  destroyCanvas()
  CANVAS && CANVAS.destroy() && (CANVAS = null)
})
</script>